package heap

type Annotation struct {
	TypeIndex            uint16
	NumElementValuePairs uint16
	Elems                []*AnnotationElem
}

type AnnotationElem struct {
	ElementNameIndex uint16
	Tag              uint8
	ConstValueIndex  uint16
}

func FormatBytesToAnnotation(annotationData []byte) []*Annotation {
	if len(annotationData) == 0 {
		return nil
	}
	annotationNumbers := uint16(annotationData[0])<<8 + uint16(annotationData[1])
	annotations := make([]*Annotation, annotationNumbers)
	var i, num, annotationElemSize uint16
	i = 2
	for num = 0; num < annotationNumbers; num++ {
		for {
			if int(i) >= len(annotationData) {
				break
			}
			typeIndex := uint16(annotationData[i])<<8 + uint16(annotationData[i+1])
			numElementValuePairs := uint16(annotationData[i+2])<<8 + uint16(annotationData[i+3])
			i += 4
			annotationElemSize = 5
			annotationsElems := make([]*AnnotationElem, numElementValuePairs)

			if int(i+annotationElemSize*numElementValuePairs-1) > len(annotationData) {
				break
			}

			var j uint16
			for j = 0; j < numElementValuePairs; j++ {
				elementNameIndex := uint16(annotationData[i])<<8 + uint16(annotationData[i+1])
				tag := uint8(annotationData[i+2])
				constValueIndex := uint16(annotationData[i+3])<<8 + uint16(annotationData[i+4])
				i += 5
				annotationsElems[j] = &AnnotationElem{elementNameIndex, tag, constValueIndex}
			}
			annotations[num] = &Annotation{typeIndex, numElementValuePairs, annotationsElems}
		}
	}
	return annotations
}
